package com.quanyan.runningriding.service.impl;

import com.quanyan.api.APIResponse;
import com.quanyan.common.utils.CommonUtils;
import com.quanyan.common.utils.Configure;
import com.quanyan.common.utils.StringUtil;
import com.quanyan.runningriding.constans.PublicConstans;
import com.quanyan.runningriding.entity.db.*;
import com.quanyan.runningriding.entity.vo.run.req.RunUserVo;
import com.quanyan.runningriding.entity.vo.run.resp.UserLevelInfo;
import com.quanyan.runningriding.mapper.RunRecordMapper;
import com.quanyan.runningriding.mapper.TbRunLevelMapper;
import com.quanyan.runningriding.mapper.TbRunRecordMapper;
import com.quanyan.runningriding.mapper.TbRunUserMapper;
import com.quanyan.runningriding.service.RunUserService;
import com.quanyan.runningriding.util.CommonUtil;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * RunRecordServiceImpl
 *
 * @author Tu Chun
 * @date 2016/8/23
 */
@Service
public class RunUserServiceImpl implements RunUserService {
    @Autowired
    private TbRunUserMapper tbRunUserMapper;

    @Autowired
    private TbRunRecordMapper tbRunRecordMapper;

    @Autowired
    private TbRunLevelMapper tbRunLevelMapper;

    @Autowired
    private RunRecordMapper runRecordMapper;

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public APIResponse<?> login(RunUserVo runUserVo) throws UnsupportedEncodingException {
        TbRunUserExample tbRunUserExample = new TbRunUserExample();
        tbRunUserExample.createCriteria().andUserIdEqualTo(runUserVo.getUserId());
        List<TbRunUser> runUsers = tbRunUserMapper.selectByExample(tbRunUserExample);

        //用户来源 1 微信 、2 qq、3游客
        Byte type = runUserVo.getUserSource();
        TbRunUser tbRunUser = new TbRunUser();
        if (type == 3) {
            tbRunUser.setNickname("游客");
            tbRunUser.setPhoto(Configure.getPropertyBykey("tourist.photo"));
            Byte gender = (!StringUtil.isBlankOrNull(Configure.getPropertyBykey("tourist.gender"))) ? Byte.parseByte(Configure.getPropertyBykey("tourist.gender")) : 1;
            tbRunUser.setGender(gender);
        } else {
            tbRunUser.setNickname(runUserVo.getNickname());
            tbRunUser.setGender(runUserVo.getGender());
            tbRunUser.setPhoto(runUserVo.getPhoto());
        }

        //设置高度
        Double height = runUserVo.getHeight() == null ? 0.0 : runUserVo.getHeight();
        if (height >= 1.00 && height <= 2.30){
            tbRunUser.setHeight(height);
        }else {
            tbRunUser.setHeight(1.70);
        }

        //设置体重
        Double weight = runUserVo.getWeight() == null ? 0.0 : runUserVo.getWeight();
        if (weight >=25.0 && weight <= 200){
            tbRunUser.setWeight(weight);
        }else {
            tbRunUser.setWeight(65.0);
        }

        //设置出生
        Integer age = runUserVo.getAge() == null ? 0 : runUserVo.getAge();
        if (age >=1930 && age <= 2006){
            tbRunUser.setAge(age);
        }else {
            tbRunUser.setAge(1985);
        }

        tbRunUser.setUserId(runUserVo.getUserId());
        tbRunUser.setAppVersion(runUserVo.getAppVersion());
        tbRunUser.setPlatform(runUserVo.getPlatform());
        tbRunUser.setUserType(runUserVo.getUserType());
        tbRunUser.setUserSource(runUserVo.getUserSource());
        tbRunUser.setCreateTime(new Date());
        tbRunUser.setUpdateTime(new Date());

        Map<String, Object> hashMap = new HashMap<String, Object>();
        hashMap.put("userId", runUserVo.getUserId());
        hashMap.put("type", runUserVo.getUserSource());


        if (runUsers != null && runUsers.size() != 0) {
            TbRunUser tbRunUser1 = runUsers.get(0);
            //用户已经登陆更新用户信息
            String token = CommonUtils.generateRunRideToken(PublicConstans.RUN_SYSTEM, tbRunUser1.getId());
            hashMap.put("token", token);
            tbRunUser.setToken(token);//更新用户token 防止用户多终端登陆
            int i = tbRunUserMapper.updateByExampleSelective(tbRunUser, tbRunUserExample);

            if (i > 0)
                return APIResponse.returnSuccess(hashMap);
            else
                return APIResponse.returnFail("用户已经登陆，更新用户信息异常");
        }

        int i = tbRunUserMapper.insertSelective(tbRunUser);

        String token = CommonUtils.generateRunRideToken(PublicConstans.RUN_SYSTEM, tbRunUser.getId());
        hashMap.put("token", token);
        tbRunUser.setToken(token);//更新用户token 防止用户多终端登陆
        //用户登陆之后更新token
        tbRunUserMapper.updateByExampleSelective(tbRunUser, tbRunUserExample);

        if (i > 0)
            return APIResponse.returnSuccess(hashMap);
        else
            return APIResponse.returnFail("登陆记录用户信息异常");
    }

    @Override
    public APIResponse<UserLevelInfo> showUserLevel(String userId) {
        //获取运动大于等于42Km的次数
        TbRunRecordExample tbRunRecordExample = new TbRunRecordExample();
        tbRunRecordExample.createCriteria()
                .andUserIdEqualTo(userId).andDistanceGreaterThanOrEqualTo(PublicConstans.RUN_KILO42);
        Integer kilo42Times = tbRunRecordMapper.countByExample(tbRunRecordExample);
        kilo42Times = kilo42Times != null ? kilo42Times : 0;
        //获取总里程
        /*Double totalMileage=runRecordMapper.userTotalMileage(userId);
        totalMileage=totalMileage!=null?totalMileage:0.00;*/
        Map<String, Object> hashMap = runRecordMapper.userTotalMileage(userId);
        Double totalMileage = MapUtils.getDouble(hashMap, "totalMileage");
        totalMileage = totalMileage != null ? totalMileage : 0.00;
        //获取42公里最小时间
        Long kilo42MinTime = runRecordMapper.kilo42MinTime(userId);
        kilo42MinTime = kilo42MinTime != null ? kilo42MinTime : 0;

        //获取用户等级
        TbRunLevelExample tbRunLevelExample = new TbRunLevelExample();
        tbRunLevelExample.createCriteria().andTotalMileageLessThanOrEqualTo(totalMileage)
                .andKilo42TimesLessThanOrEqualTo(kilo42Times)
                .andKilo42Time2GreaterThanOrEqualTo(kilo42MinTime);
        tbRunLevelExample.setOrderByClause(" level_id DESC ");
        List<TbRunLevel> runLevels = tbRunLevelMapper.selectByExample(tbRunLevelExample);
        if (runLevels == null || runLevels.size() <= 0) {
            return APIResponse.returnFail("获取用户等级异常");
        }
        TbRunLevel tbRunLevel = runLevels.get(0);
        Integer level = tbRunLevel.getLevelId();
        tbRunLevelExample.clear();
        tbRunLevelExample.setOrderByClause(" level_id ASC ");
        List<TbRunLevel> runLevels1 = tbRunLevelMapper.selectByExample(tbRunLevelExample);
        if (runLevels1 == null || runLevels1.size() == 0) {
            return APIResponse.returnFail("等级体系异常");
        }
        //获取下一个等级的公里数
        Double nextLevelKilo=0.0;
        for (TbRunLevel tbRunLevel2 : runLevels1) {
            if (tbRunLevel2.getLevelId() == level + 1) {
                nextLevelKilo=tbRunLevel2.getTotalMileage();
            }
        }
        //获取用户信息
        TbRunUserExample tbRunUserExample = new TbRunUserExample();
        tbRunUserExample.createCriteria().andUserIdEqualTo(userId);
        List<TbRunUser> runUsers = tbRunUserMapper.selectByExample(tbRunUserExample);
        TbRunUser runUser = null;
        if (runUsers != null && runUsers.size() != 0) {
            runUser = runUsers.get(0);
        }

        UserLevelInfo userLevelInfo = new UserLevelInfo();
        if (runUser != null) {
            userLevelInfo.setNickName(runUser.getNickname());
            userLevelInfo.setPhoto(runUser.getPhoto());
        }
        userLevelInfo.setLevelId(level);
        userLevelInfo.setLevelName(tbRunLevel.getLevelName());
        userLevelInfo.setTotalMileage(totalMileage);
        userLevelInfo.setRiseDistance(CommonUtil.keepTwoDecimal(nextLevelKilo != 0 ? nextLevelKilo - totalMileage : 0));
        userLevelInfo.setKilo42Time(kilo42MinTime);
        userLevelInfo.setKilo42Times(kilo42Times);
        userLevelInfo.setRunLevels(runLevels1);

        return APIResponse.returnSuccess(userLevelInfo);
    }


}
